package com.pureut.order.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.core.web.domain.AjaxResult;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.order.domain.SampleManagement;
import com.pureut.order.domain.system.domain.MaterialFinished;
import com.pureut.order.dto.MaterialFinishedDto;
import com.pureut.order.dto.SampleManagementDto;
import com.pureut.order.mapper.SampleManagementMapper;
import com.pureut.order.service.SampleManagementService;
import com.pureut.order.vo.OrderReviewVo;
import com.pureut.order.vo.SampleDetailVo;
import com.pureut.order.vo.SampleManagementVo;
import com.pureut.order.vo.SampleVo;
import com.pureut.system.api.FeignService;
import com.pureut.system.api.SchedulingPlanFeignService;
import com.pureut.system.api.domain.SysDept;
import com.pureut.system.api.domain.SysDictData;
import com.pureut.system.api.vo.SchedulingPlanVo;
import com.pureut.system.api.vo.SysAuditHistoryVo;
import com.pureut.system.api.vo.SysWorkbenchAuditAgentVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class SampleManagementServiceImpl extends ServiceImpl<SampleManagementMapper, SampleManagement> implements SampleManagementService {

    @Resource
    SampleManagementMapper sampleManagementMapper;

    @Resource
    FeignService feignService;

    @Resource
    SchedulingPlanFeignService schedulingPlanFeignService;

    /**
     * 样品管理列表
     *
     * @param sampleManagementVo
     * @return
     */
    @Override
    @DataScope(deptAlias = "a")
    public List<SampleManagementDto> getList(SampleManagementVo sampleManagementVo) {

        List<SampleManagementDto> sampleManagementList = sampleManagementMapper.getSampleManagementList(sampleManagementVo);

        //获取网型标准缓存字典数据
        List<SysDictData> netArray = DictUtils.getDictCache("sys_of_type");
        Map<String, String> netMap = netArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取铺网类型标准缓存字典数据
        List<SysDictData> netTypeArray = DictUtils.getDictCache("sys_type_net");
        Map<String, String> netTypeMap = netTypeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取样品状态缓存字典数据
        List<SysDictData> array = DictUtils.getDictCache("sample_status");
        Map<String, String> arrayMap = array.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取样品质量标准缓存字典数据
        List<SysDictData> standardArray = DictUtils.getDictCache("sample_standard");
        Map<String, String> standardMap = standardArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取样品类型标准缓存字典数据
        List<SysDictData> typeArray = DictUtils.getDictCache("sample_type");
        Map<String, String> typeMap = typeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取基础物料表物料类别缓存字典数据
        List<SysDictData> sysTypeArray = DictUtils.getDictCache("sys_material_type");
        Map<String, String> sysTypeMap = sysTypeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        for (SampleManagementDto entity : sampleManagementList) {
            entity.setMaterialNetDict(netMap.get(entity.getMaterialNet()));
            entity.setMaterialNetTypeDict(netTypeMap.get(entity.getMaterialNetType()));
            entity.setMaterialNetType(String.valueOf(entity.getMaterialNetType()));
            entity.setSampleStatusDict(arrayMap.get(String.valueOf(entity.getSampleStatus())));

            entity.setQualityStandardDict(standardMap.get(entity.getQualityStandard()));

            entity.setMaterialTypeDict(typeMap.get(String.valueOf(entity.getMaterialType())));

            entity.setMaterialCategoryDict(sysTypeMap.get(String.valueOf(entity.getMaterialCategory())));

            //获取部门信息
            AjaxResult deptInfo = feignService.getDeptInfo(entity.getDemandDepartment());
            SysDept data = JSON.parseObject(JSON.toJSONString(deptInfo.get("data")), SysDept.class);
            entity.setDemandDepartmentDict(data.getDeptName());

        }
        return sampleManagementList;
    }

    /**
     * 新增样品
     *
     * @param sampleManagementVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveSample(SampleManagementVo sampleManagementVo) throws Exception {
        List<SampleVo> sampleList = sampleManagementVo.getSampleList();
        List<SampleManagement> sampleManagementList = new ArrayList<>();
        for (SampleVo entity : sampleList) {
            SampleManagement sampleManagement = new SampleManagement();
            String authorityCoding = feignService.getAuthorityCoding("order:sample:list");
            if (authorityCoding == null) {
                throw new GlobalException("未进行单据配置,单据编码生成失败");
            }
            sampleManagement.setSampleOrderNum(authorityCoding)
                    .setDeptId(SecurityUtils.getDeptId())
                    .setMaterialId(entity.getMaterialId())
                    .setMaterialType(4)
                    .setMaterialCategory(entity.getMaterialCategory())
                    .setSampleStatus(1)
                    .setMaterialCode(entity.getMaterialCode())
                    .setDemandDepartment(sampleManagementVo.getDemandDepartment())
                    .setCreateBy(SecurityUtils.getUsername())
                    .setCreateTime(new Date())
                    .setRemark(sampleManagementVo.getRemark())
                    .setThickness(entity.getThickness())
                    .setProofingWeight(entity.getProofingWeight())
                    .setQualityStandard(entity.getQualityStandard())
                    .setDeliveryDate(entity.getDeliveryDate());
            sampleManagementList.add(sampleManagement);
        }
        return saveBatch(sampleManagementList);
    }


    /**
     * 修改样品
     *
     * @param sampleManagementVo
     * @return
     */
    @Override
    public boolean updateSample(SampleManagementVo sampleManagementVo) {
        SampleManagement sampleManagement = getById(sampleManagementVo.getId());
        if (sampleManagement.getSampleStatus() == 1 || sampleManagement.getSampleStatus() == 5 || sampleManagement.getSampleStatus() == 8) {
            List<SampleVo> sampleList = sampleManagementVo.getSampleList();
            for (SampleVo entity : sampleList) {
                sampleManagement.setDemandDepartment(sampleManagementVo.getDemandDepartment())
                        .setRemark(sampleManagementVo.getRemark())
                        .setThickness(entity.getThickness())
                        .setProofingWeight(entity.getProofingWeight())
                        .setQualityStandard(entity.getQualityStandard())
                        .setMaterialCode(entity.getMaterialCode())
                        .setMaterialId(entity.getMaterialId())
                        .setMaterialCategory(entity.getMaterialCategory());
            }
            if (sampleManagement.getSampleStatus() == 5 || sampleManagement.getSampleStatus() == 8) {
                //调用审核
                SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
                String perms = "order:sample:review";
                String auditDoc = sampleManagement.getSampleOrderNum();
                sysAuditHistoryVo.setAuditDoc(auditDoc);
                sysAuditHistoryVo.setPerms(perms);
                AjaxResult history = feignService.editHistory(sysAuditHistoryVo);
                String data = JSON.parseObject(JSON.toJSONString(history.get("msg")), String.class);
                if ("操作成功".equals(data)) {
                    sampleManagement.setSampleStatus(1);

                    //修改审核代办状态为已处理
                    feignService.updateStatus(3,sampleManagement.getSampleOrderNum(),"样品管理");//

                    return updateById(sampleManagement);
                } else {
                    return false;
                }
            }
            return updateById(sampleManagement);
        } else {
            throw new GlobalException("仅可对待提交、未通过、已退回的样品信息进行修改");
        }
    }

    /**
     * 提交审核
     *
     * @param id
     * @return
     */
    @Override
    public boolean submitReview(Long id) {
        SampleManagement sampleManagement = getById(id);
        if (sampleManagement.getSampleStatus() == 1) {
            sampleManagement.setSampleStatus(2);

            SysWorkbenchAuditAgentVo sysWorkbenchAuditAgentVo = new SysWorkbenchAuditAgentVo();
            sysWorkbenchAuditAgentVo.setDocConfig("order:sample:review");
            sysWorkbenchAuditAgentVo.setReceiptName("样品管理");
            sysWorkbenchAuditAgentVo.setReceiptNumber(sampleManagement.getSampleOrderNum());//
            sysWorkbenchAuditAgentVo.setStatus(1);//待审核
            sysWorkbenchAuditAgentVo.setReceiptContent("有单据待审核,请及时审核");

            feignService.insertAuditAgent(sysWorkbenchAuditAgentVo);

            return updateById(sampleManagement);
        } else {
            throw new GlobalException("只能操作待提交的数据");
        }

    }

    /**
     * 撤销审核
     *
     * @param id
     * @return
     */
    @Override
    public boolean deleteReview(Long id) {
        SampleManagement sampleManagement = getById(id);
        if (2 == sampleManagement.getSampleStatus()) {
            sampleManagement.setSampleStatus(1);

            feignService.deleteDoc(sampleManagement.getSampleOrderNum(),"样品管理");

            return updateById(sampleManagement);
        } else {
            throw new GlobalException("不是待审核样品，无法撤销");
        }
    }

    /**
     * 删除样品
     *
     * @param ids
     * @return
     */
    @Override
    public boolean deleteSample(String ids) {
        List<String> idList = Arrays.asList(ids.split(","));
        LambdaQueryWrapper<SampleManagement> wrapper = new QueryWrapper<SampleManagement>().lambda().in(SampleManagement::getId, idList);
        //获取勾选的样品对象
        List<SampleManagement> sampleManagementList = sampleManagementMapper.selectList(wrapper);



        //过滤掉状态不为待提交的对象
        List<SampleManagement> collect = sampleManagementList.stream().filter(c -> 1 == c.getSampleStatus()).collect(Collectors.toList());
        if (collect.size() > 0) {

            for (SampleManagement sampleManagement : sampleManagementList) {
                feignService.deleteDoc(sampleManagement.getSampleOrderNum(),"样品管理");
            }

            return sampleManagementMapper.deleteBatchIds(collect) > 0;
        } else {
            throw new GlobalException("没有满足删除要求得样品");
        }
    }

    /**
     * 查看样品
     *
     * @param id
     * @return
     */
    @Override
    public SampleManagementDto getSampleById(Long id) {
        SampleManagementDto sampleManagementDto = new SampleManagementDto();
        SampleManagement sampleManagement = getById(id);

        //获取网型标准缓存字典数据
        List<SysDictData> netArray = DictUtils.getDictCache("sys_of_type");
        Map<String, String> netMap = netArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取铺网类型标准缓存字典数据
        List<SysDictData> netTypeArray = DictUtils.getDictCache("sys_type_net");
        Map<String, String> netTypeMap = netTypeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取样品状态缓存字典数据
        List<SysDictData> array = DictUtils.getDictCache("sample_status");
        Map<String, String> arrayMap = array.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取样品质量标准缓存字典数据
        List<SysDictData> standardArray = DictUtils.getDictCache("sample_standard");
        Map<String, String> standardMap = standardArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取样品类型标准缓存字典数据
        List<SysDictData> typeArray = DictUtils.getDictCache("sample_type");
        Map<String, String> typeMap = typeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取基础物料表物料类别缓存字典数据
        List<SysDictData> sysTypeArray = DictUtils.getDictCache("sys_material_type");
        Map<String, String> sysTypeMap = sysTypeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        SampleDetailVo sampleDetailVo = new SampleDetailVo();
        //如果是成品
        if (4 == sampleManagement.getMaterialType()) {
            AjaxResult info = feignService.getInfo(sampleManagement.getMaterialId());
            MaterialFinished data = JSON.parseObject(JSON.toJSONString(info.get("detailed")), MaterialFinished.class);
            sampleDetailVo.setMaterialName(data.getMaterialName());
            sampleDetailVo.setMaterialCode(data.getMaterialCode());
            sampleDetailVo.setMaterialSpec(data.getMaterialSpec());
            sampleDetailVo.setMaterialNet(String.valueOf(data.getMaterialNet()));
            sampleDetailVo.setMaterialNetType(String.valueOf(data.getMaterialNetType()));
            sampleDetailVo.setMaterialSpec(data.getMaterialSpec());
            sampleDetailVo.setMaterialRatio(data.getMaterialRatio());
            sampleDetailVo.setMaterialCategory(data.getMaterialType());
            sampleDetailVo.setMaterialNetDict(netMap.get(String.valueOf(data.getMaterialNet())));
            sampleDetailVo.setMaterialNetTypeDict(netTypeMap.get(String.valueOf(data.getMaterialNetType())));
            sampleDetailVo.setMaterialGheavy(String.valueOf(data.getMaterialGheavy()));
        }
        sampleManagementDto.setMaterialTypeDict(typeMap.get(String.valueOf(sampleManagementDto.getMaterialType())));

        sampleManagementDto.setSampleStatusDict(arrayMap.get(String.valueOf(sampleManagement.getSampleStatus())));

        sampleManagementDto.setMaterialTypeDict(typeMap.get(String.valueOf(sampleManagement.getMaterialType())));

        sampleDetailVo.setMaterialCategoryDict(sysTypeMap.get(String.valueOf(sampleManagement.getMaterialCategory())));

        //获取部门信息
        AjaxResult deptInfo = feignService.getDeptInfo(sampleManagement.getDemandDepartment());
        SysDept data = JSON.parseObject(JSON.toJSONString(deptInfo.get("data")), SysDept.class);
        sampleManagementDto.setDemandDepartmentDict(data.getDeptName());

        sampleManagementDto.setSampleOrderNum(sampleManagement.getSampleOrderNum());
        sampleManagementDto.setSampleStatus(sampleManagement.getSampleStatus());
        sampleManagementDto.setMaterialType(sampleManagement.getMaterialType());
        sampleManagementDto.setMaterialId(sampleManagement.getMaterialId());
        sampleManagementDto.setDemandDepartment(sampleManagement.getDemandDepartment());
        sampleDetailVo.setProofingWeight(sampleManagement.getProofingWeight());
        sampleDetailVo.setDeliveryDate(sampleManagement.getDeliveryDate());
        sampleDetailVo.setThickness(sampleManagement.getThickness());
        sampleDetailVo.setQualityStandard(String.valueOf(sampleManagement.getQualityStandard()));
        sampleDetailVo.setQualityStandardDict(standardMap.get(String.valueOf(sampleManagement.getQualityStandard())));
        sampleManagementDto.setQualityStandard(String.valueOf(sampleManagement.getQualityStandard()));
        sampleManagementDto.setCreateBy(sampleManagement.getCreateBy());
        sampleManagementDto.setCreateTime(sampleManagement.getCreateTime());
        sampleManagementDto.setReviewBy(sampleManagement.getReviewBy());
        sampleManagementDto.setReviewTime(sampleManagement.getReviewTime());
        sampleManagementDto.setRemark(sampleManagement.getRemark());
        sampleManagementDto.setBackReason(sampleManagement.getBackReason());
        sampleManagementDto.setStopReason(sampleManagement.getStopReason());
        sampleManagementDto.setId(sampleManagement.getId());
        List<SampleDetailVo> sampleDetailVoList = new ArrayList<>();
        sampleDetailVoList.add(sampleDetailVo);
        sampleManagementDto.setSampleList(sampleDetailVoList);
        return sampleManagementDto;
    }


    /**
     * 样品审核
     *
     * @param orderReviewVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean sampleReview(OrderReviewVo orderReviewVo) throws Exception {

        SampleManagement sampleManagement = getById(orderReviewVo.getId());
        if (sampleManagement.getSampleStatus() == 2 || sampleManagement.getSampleStatus() == 3) {
            String perms = "order:sample:review";
            int isAdopt = orderReviewVo.getIsAdopt();
            String auditDoc = sampleManagement.getSampleOrderNum();
            String auditRemarks = orderReviewVo.getReviewComments();
            Long userId = SecurityUtils.getUserId();
            AjaxResult sequence = feignService.getSequenceTwo(perms, 2, isAdopt, auditRemarks, auditDoc, userId);
            Integer data = JSON.parseObject(JSON.toJSONString(sequence.get("data")), Integer.class);
            if (data == null) {
                throw new GlobalException("未对该审核进行配置");
            }
            //1:通过，2：审核中，3：没权限 4:该人已经审核过
            if (orderReviewVo.getIsAdopt() == 1) {
                if (data == 1) {
                    sampleManagement.setSampleStatus(6);
                    if (sampleManagement.getReviewBy() == null) {
                        sampleManagement.setReviewBy(SecurityUtils.getUsername());
                    } else {
                        sampleManagement.setReviewBy(sampleManagement.getReviewBy() + "," + SecurityUtils.getUsername());
                    }
                    sampleManagement.setReviewTime(new Date());
                    updateById(sampleManagement);
                    //生成计划单数据
                    List<SchedulingPlanVo> schedulingPlanVoList = new ArrayList<>();
                    SchedulingPlanVo schedulingPlanVo = new SchedulingPlanVo();
                    schedulingPlanVo.setPlanId(sampleManagement.getId());
                    schedulingPlanVo.setPlanNote(sampleManagement.getRemark());
                    schedulingPlanVo.setPlanType(2);
                    schedulingPlanVo.setPlanContractWeight(sampleManagement.getProofingWeight());
                    schedulingPlanVo.setPlanDeliveryTime(sampleManagement.getDeliveryDate());
                    schedulingPlanVo.setPlanMaterialId(sampleManagement.getMaterialId());
                    schedulingPlanVo.setPlanAssociatedId(sampleManagement.getId());
                    schedulingPlanVo.setPlanAssociatedCode(sampleManagement.getSampleOrderNum());
                    schedulingPlanVo.setPlanMaterialCode(sampleManagement.getMaterialCode());

                    AjaxResult info = feignService.getInfo(sampleManagement.getMaterialId());
                    MaterialFinishedDto detailed = JSON.parseObject(JSON.toJSONString(info.get("detailed")), MaterialFinishedDto.class);
                    schedulingPlanVo.setPlanMaterialName(detailed.getMaterialName());
                    schedulingPlanVo.setPlanMaterialSpec(detailed.getMaterialSpec());
                    schedulingPlanVoList.add(schedulingPlanVo);

                    AjaxResult add = schedulingPlanFeignService.addPlan(schedulingPlanVoList);
                    String code = add.get("code").toString();

                    feignService.updateStatus(3,sampleManagement.getSampleOrderNum(),"样品管理");

                    return "200".equals(code);
                } else if (data == 2) {
                    sampleManagement.setSampleStatus(3);
                    if (sampleManagement.getReviewBy() == null) {
                        sampleManagement.setReviewBy(SecurityUtils.getUsername());
                    } else {
                        sampleManagement.setReviewBy(sampleManagement.getReviewBy() + "," + SecurityUtils.getUsername());
                    }
                    sampleManagement.setReviewTime(new Date());
                    return updateById(sampleManagement);
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            } else {
                if (data == 1 || data == 2) {
                    sampleManagement.setSampleStatus(5);
                    if (sampleManagement.getReviewBy() == null) {
                        sampleManagement.setReviewBy(SecurityUtils.getUsername());
                    } else {
                        sampleManagement.setReviewBy(sampleManagement.getReviewBy() + "," + SecurityUtils.getUsername());
                    }
                    sampleManagement.setReviewTime(new Date());

                    SysWorkbenchAuditAgentVo sysWorkbenchAuditAgentVo = new SysWorkbenchAuditAgentVo();
                    sysWorkbenchAuditAgentVo.setDocConfig("order:sample:review");
                    sysWorkbenchAuditAgentVo.setReceiptName("样品管理");
                    sysWorkbenchAuditAgentVo.setReceiptNumber(sampleManagement.getSampleOrderNum());//
                    sysWorkbenchAuditAgentVo.setStatus(2);//待审核

                    sysWorkbenchAuditAgentVo.setPassFlag("1");
                    sysWorkbenchAuditAgentVo.setCreateName(sampleManagement.getCreateBy());

                    sysWorkbenchAuditAgentVo.setReceiptContent("有单据未通过,请及时查看");

                    feignService.insertAuditAgent(sysWorkbenchAuditAgentVo);

                    return updateById(sampleManagement);
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            }
        } else {
            throw new GlobalException("只能对待审核和审核中的数据进行处理");
        }
    }
}
